<template>
  <div class="base-geo-container">
    <div class="map-header">
      <h2>北京朝阳区国贸地区基站分布图</h2>
      <div class="header-controls">
        <div class="time-selector">
          <label for="moment-select">时刻选择:</label>
          <div class="time-info">
            <span class="current-time">当前: {{ formatMoment(getCurrentMoment()) }}</span>
            <span class="auto-refresh-indicator" :class="{ active: refreshTimer }">
              🔄 自动刷新
            </span>
          </div>
          <select 
            id="moment-select" 
            v-model="CURRENT_MOMENT" 
            @change="onMomentChange"
            class="moment-select"
          >
            <option v-for="moment in availableMoments" :key="moment" :value="moment">
              {{ formatMoment(moment) }}
            </option>
          </select>
        </div>
        <div class="zoom-info">
          <span>缩放级别: {{ currentZoomLevel }}</span>
          <span class="zoom-hint">{{ currentZoomLevel >= 15 ? '详细视图' : '聚合视图' }}</span>
          <button 
            class="reset-view-btn" 
            @click="resetToDefaultView"
            :disabled="isDefaultView"
            :title="isDefaultView ? '当前已是默认视角' : '点击回到默认视角'"
          >
            <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
              <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
            </svg>
            重置视角
          </button>
        </div>
        <div class="legend">
          <div class="legend-item">
            <div class="legend-icon triangle"></div>
            <span>基站 ({{ baseStations.length }}个)</span>
          </div>
          <div class="legend-item">
            <div class="legend-icon circle"></div>
            <span>用户 ({{ users.length }}个)</span>
          </div>
          <div v-if="isLoading" class="legend-item loading">
            <div class="loading-spinner"></div>
            <span>加载中...</span>
          </div>
          <div v-if="loadingError" class="legend-item error">
            <div class="error-icon">⚠</div>
            <span>{{ loadingError }}</span>
          </div>
        </div>
      </div>
    </div>
    <div id="map" class="map-container"></div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref, computed } from 'vue'
import L from 'leaflet'

// 地图实例
let map: L.Map | null = null

// 后端API配置
const API_BASE_URL = '/basestation-api' // 使用代理路径

// 获取当前实时时间（秒），取整到分钟
const getCurrentMoment = () => {
  const now = new Date()
  const totalSeconds = now.getHours() * 3600 + now.getMinutes() * 60
  return totalSeconds // 已经是分钟的整数倍
}

const CURRENT_MOMENT = ref(getCurrentMoment()) // 当前时刻，实时时间

// 当前地图缩放级别
const currentZoomLevel = ref(15)

// 计算基站的边界和中心点
const calculateBaseStationBounds = (stations: any[]) => {
  if (stations.length === 0) {
    return {
      center: { lat: 39.9065, lng: 116.4574 },
      zoom: 15
    };
  }

  const lats = stations.map(station => station.lat);
  const lngs = stations.map(station => station.lng);
  
  const minLat = Math.min(...lats);
  const maxLat = Math.max(...lats);
  const minLng = Math.min(...lngs);
  const maxLng = Math.max(...lngs);
  
  // 计算中心点
  const centerLat = (minLat + maxLat) / 2;
  const centerLng = (minLng + maxLng) / 2;
  
  // 计算范围
  const latRange = maxLat - minLat;
  const lngRange = maxLng - minLng;
  const maxRange = Math.max(latRange, lngRange);
  
  // 根据范围计算合适的缩放级别
  let zoom = 17;
  if (maxRange > 0.1) zoom = 12;
  else if (maxRange > 0.05) zoom = 14;
  else if (maxRange > 0.02) zoom = 15;
  else if (maxRange > 0.01) zoom = 16;
  else if (maxRange > 0.005) zoom = 17;
  else zoom = 18;
  
  console.log(`计算的基站范围: 纬度${minLat.toFixed(6)}-${maxLat.toFixed(6)}, 经度${minLng.toFixed(6)}-${maxLng.toFixed(6)}`);
  console.log(`中心点: (${centerLat.toFixed(6)}, ${centerLng.toFixed(6)}), 缩放级别: ${zoom}`);
  
  return {
    center: { lat: centerLat, lng: centerLng },
    zoom: zoom,
    bounds: { minLat, maxLat, minLng, maxLng }
  };
}

// 动态默认视角配置
const DEFAULT_VIEW = ref({
  lat: 39.9065,
  lng: 116.4574,
  zoom: 15
})

// 当前地图中心点
const currentCenter = ref({ lat: DEFAULT_VIEW.value.lat, lng: DEFAULT_VIEW.value.lng })

// 判断是否为默认视角
const isDefaultView = computed(() => {
  return currentZoomLevel.value === DEFAULT_VIEW.value.zoom &&
         Math.abs(currentCenter.value.lat - DEFAULT_VIEW.value.lat) < 0.001 &&
         Math.abs(currentCenter.value.lng - DEFAULT_VIEW.value.lng) < 0.001
})

// 聚合的标记层
let baseStationMarkers: L.LayerGroup | null = null
let userMarkers: L.LayerGroup | null = null

// 真实的基站和用户数据
const baseStations = ref<any[]>([])
const users = ref<any[]>([])
const isLoading = ref(false)
const loadingError = ref<string | null>(null)

// 可用的时刻选项（当天从00:00到当前时间的每分钟）
const availableMoments = computed(() => {
  const moments = []
  const currentSeconds = getCurrentMoment()
  
  // 从00:00开始，每分钟一个时刻，直到当前时间
  for (let seconds = 0; seconds <= currentSeconds; seconds += 60) {
    moments.push(seconds)
  }
  
  return moments.reverse() // 最新时间在前
})

// 自动刷新定时器
const refreshTimer = ref<number | null>(null)

// 格式化时刻显示
const formatMoment = (moment: number): string => {
  const hours = Math.floor(moment / 3600)
  const minutes = Math.floor((moment % 3600) / 60)
  const seconds = moment % 60
  return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
}

// 时刻变化处理
const onMomentChange = async () => {
  console.log(`切换到时刻: ${formatMoment(CURRENT_MOMENT.value)}`)
  await loadRealData()
  if (map && !isLoading.value && !loadingError.value) {
    updateMarkers()
  }
}

// 自动刷新数据
const startAutoRefresh = () => {
  // 清除现有定时器
  if (refreshTimer.value) {
    clearInterval(refreshTimer.value)
  }
  
  // 设置每分钟刷新一次
  refreshTimer.value = setInterval(async () => {
    const newMoment = getCurrentMoment()
    if (newMoment !== CURRENT_MOMENT.value) {
      console.log(`自动更新到新时刻: ${formatMoment(newMoment)}`)
      CURRENT_MOMENT.value = newMoment
      await loadRealData()
      if (map && !isLoading.value && !loadingError.value) {
        updateMarkers()
      }
    }
  }, 60000) // 每60秒检查一次
}

// 停止自动刷新
const stopAutoRefresh = () => {
  if (refreshTimer.value) {
    clearInterval(refreshTimer.value)
    refreshTimer.value = null
  }
}

// 针对北京国贸地区优化的UTM到WGS84转换函数
const beijingUtmToLatLng = (x: number, y: number) => {
  console.log(`输入原始UTM坐标: x=${x}, y=${y}`);
  
  // 根据实际的北京地区UTM Zone 50N坐标系统
  // 国贸中心实际UTM坐标应该在450000-460000和4415000-4425000范围内
  
  // 使用更准确的北京国贸地区参考点
  // 经过在线UTM转换工具验证的坐标
  const refLat = 39.9065;    // 国贸中心纬度
  const refLng = 116.4574;   // 国贸中心经度
  const refUtmX = 452574;    // 更准确的UTM X坐标
  const refUtmY = 4418065;   // 更准确的UTM Y坐标
  
  console.log(`使用参考点: UTM(${refUtmX}, ${refUtmY}) -> WGS84(${refLat}, ${refLng})`);
  
  // 北京地区的精确转换系数（基于UTM Zone 50N）
  const metersPerDegreeLat = 111320.0;  // 纬度方向每度的米数
  const metersPerDegreeLng = 91287.0;   // 经度方向每度的米数（在北京纬度39.9°）
  
  // 计算相对偏移
  const deltaX = x - refUtmX;
  const deltaY = y - refUtmY;
  
  console.log(`坐标偏移: deltaX=${deltaX}, deltaY=${deltaY}`);
  
  // 转换为经纬度偏移
  const deltaLat = deltaY / metersPerDegreeLat;
  const deltaLng = deltaX / metersPerDegreeLng;
  
  console.log(`经纬度偏移: deltaLat=${deltaLat}, deltaLng=${deltaLng}`);
  
  // 计算最终坐标
  const lat = refLat + deltaLat;
  const lng = refLng + deltaLng;
  
  console.log(`北京UTM转换结果: (${x}, ${y}) -> (${lat.toFixed(8)}, ${lng.toFixed(8)})`);
  return { lat, lng };
}

// 备用转换函数（如果主转换失败）
const fallbackUtmToLatLng = (x: number, y: number) => {
  // 更保守的转换方法，基于已知的多个参考点
  const refPoints = [
    { utmX: 454149, utmY: 4419008, lat: 39.9066, lng: 116.4575 },
    { utmX: 454071, utmY: 4418096, lat: 39.8983, lng: 116.4566 },
    { utmX: 454500, utmY: 4419000, lat: 39.9065, lng: 116.4614 }
  ];
  
  // 找到最近的参考点
  let minDist = Infinity;
  let bestRef = refPoints[0];
  
  refPoints.forEach(ref => {
    const dist = Math.sqrt((x - ref.utmX) ** 2 + (y - ref.utmY) ** 2);
    if (dist < minDist) {
      minDist = dist;
      bestRef = ref;
    }
  });
  
  // 基于最近参考点进行线性插值
  const deltaX = x - bestRef.utmX;
  const deltaY = y - bestRef.utmY;
  
  const lat = bestRef.lat + deltaY / 111132.92;
  const lng = bestRef.lng + deltaX / 85393.74;
  
  console.log(`备用UTM转换: (${x}, ${y}) -> (${lat.toFixed(8)}, ${lng.toFixed(8)})`);
  return { lat, lng };
}

// 特殊转换函数：处理可能已经是修正后经纬度的情况
const specialCoordinateTransform = (x: number, y: number) => {
  // 基于观察到的坐标模式：纬度约0.14，经度约111.14
  // 可能需要加上偏移量来转换到正确的北京坐标
  
  // 如果x和y都很小，可能需要加上基础偏移
  let lat, lng;
  
  if (Math.abs(x) < 10 && Math.abs(y) < 200) {
    // 情况1：坐标可能是相对于某个基准点的偏移
    lat = 39.9065 + y;  // 以国贸为基准
    lng = 116.4574 + x;
  } else if (x > 100 && y < 10) {
    // 情况2：x可能是经度偏移，y可能是纬度偏移
    lat = 39.9065 + y;
    lng = x;
  } else {
    // 情况3：直接作为经纬度使用，但可能需要调整
    lat = y;
    lng = x;
    
    // 如果经度看起来不对（太小），可能需要调整
    if (lng < 50) {
      lng = 116.4574 + x;
    }
    
    // 如果纬度看起来不对（太小），可能需要调整  
    if (lat < 10) {
      lat = 39.9065 + y;
    }
  }
  
  console.log(`特殊坐标转换: (${x}, ${y}) -> (${lat.toFixed(8)}, ${lng.toFixed(8)})`);
  return { lat, lng };
}

// UTM Zone 50N 转 WGS84 经纬度转换函数（专门针对北京地区优化）
const utmToLatLng = (x: number, y: number) => {
  console.log(`输入UTM坐标: x=${x}, y=${y}`);
  
  // 首先检查坐标是否合理
  if (isNaN(x) || isNaN(y) || x === 0 || y === 0) {
    console.warn(`无效的UTM坐标: x=${x}, y=${y}`);
    return { lat: DEFAULT_VIEW.value.lat, lng: DEFAULT_VIEW.value.lng }; // 返回默认位置
  }
  
  // 检查坐标模式，确定使用哪种转换方法
  if (Math.abs(x) < 10 && Math.abs(y) < 10) {
    // 坐标值很小，可能是相对偏移量
    console.log(`检测到小数值坐标，使用特殊转换`);
    return specialCoordinateTransform(x, y);
  } else if (x > 400000 && x < 500000 && y > 4000000 && y < 5000000) {
    // 标准UTM坐标范围
    console.log(`检测到标准UTM坐标，使用UTM转换`);
    const result = beijingUtmToLatLng(x, y);
    
    // 验证结果是否在合理范围内（北京地区）
    if (result.lat < 39.7 || result.lat > 40.2 || result.lng < 116.0 || result.lng > 117.0) {
      console.warn(`转换结果可能不准确: lat=${result.lat}, lng=${result.lng}，使用备用转换`);
      return fallbackUtmToLatLng(x, y);
    }
    
    return result;
  } else {
    // 其他情况，尝试特殊转换
    console.log(`坐标格式未知，尝试特殊转换`);
    return specialCoordinateTransform(x, y);
  }
}

// 测试UTM转换函数的准确性
const testUtmConversion = () => {
  console.log('=== UTM转换测试 ===');
  
  // 测试用例1：参考Python代码的示例
  const testCase1 = { x: 454149.007301644, y: 4419008.48441096 };
  const result1 = utmToLatLng(testCase1.x, testCase1.y);
  console.log(`测试用例1: UTM(${testCase1.x}, ${testCase1.y}) -> WGS84(${result1.lat.toFixed(8)}, ${result1.lng.toFixed(8)})`);
  
  // 测试用例2：国贸中心附近
  const testCase2 = { x: 454071.630204392, y: 4418096.37790294 };
  const result2 = utmToLatLng(testCase2.x, testCase2.y);
  console.log(`测试用例2: UTM(${testCase2.x}, ${testCase2.y}) -> WGS84(${result2.lat.toFixed(8)}, ${result2.lng.toFixed(8)})`);
  
  // 测试用例3：国贸中心参考点
  const testCase3 = { x: 454500, y: 4419000 };
  const result3 = utmToLatLng(testCase3.x, testCase3.y);
  console.log(`测试用例3(国贸中心): UTM(${testCase3.x}, ${testCase3.y}) -> WGS84(${result3.lat.toFixed(8)}, ${result3.lng.toFixed(8)})`);
  
  // 测试用例4：实际观察到的小数值坐标
  const testCase4 = { x: 0.14359830432182008, y: 111.14058336179478 };
  const result4 = utmToLatLng(testCase4.x, testCase4.y);
  console.log(`测试用例4(实际坐标): (${testCase4.x}, ${testCase4.y}) -> WGS84(${result4.lat.toFixed(8)}, ${result4.lng.toFixed(8)})`);
  
  // 测试不同转换方法的对比
  const beijing1 = beijingUtmToLatLng(testCase1.x, testCase1.y);
  const fallback1 = fallbackUtmToLatLng(testCase1.x, testCase1.y);
  const special4 = specialCoordinateTransform(testCase4.x, testCase4.y);
  console.log(`北京转换1: UTM(${testCase1.x}, ${testCase1.y}) -> WGS84(${beijing1.lat.toFixed(8)}, ${beijing1.lng.toFixed(8)})`);
  console.log(`备用转换1: UTM(${testCase1.x}, ${testCase1.y}) -> WGS84(${fallback1.lat.toFixed(8)}, ${fallback1.lng.toFixed(8)})`);
  console.log(`特殊转换4: (${testCase4.x}, ${testCase4.y}) -> WGS84(${special4.lat.toFixed(8)}, ${special4.lng.toFixed(8)})`);
  
  console.log('=== 测试完成 ===');
};

// 获取基站位置信息
const fetchBaseStationLocations = async () => {
  try {
    console.log('正在获取基站位置信息...')
    const response = await fetch(`${API_BASE_URL}/getlocation_bs`)
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    
    const data = await response.json()
    console.log('基站位置数据:', data)
    
    const locations: any[] = []
    Object.entries(data).forEach(([bsId, info]: [string, any]) => {
      locations.push({
        id: parseInt(bsId),
        name: `基站${bsId}`,
        lat: info.longlat_position[1],
        lng: info.longlat_position[0],
        transmit_power: info.transmit_power,
        poi_grid: info.poi_grid,
        xy_position: info.xy_position
      })
    })
    
    console.log(`成功加载 ${locations.length} 个基站位置`)
    return locations
  } catch (error) {
    console.error('获取基站位置失败:', error)
    // 返回空数组而不是抛出错误，让应用继续运行
    return []
  }
}

// 获取基站状态信息
const fetchBaseStationData = async (moment: number) => {
  try {
    console.log(`正在获取时刻 ${moment} 的基站状态信息...`)
    const response = await fetch(`${API_BASE_URL}/getmapdata_bs?moment=${moment}`)
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    
    const data = await response.json()
    console.log('基站状态数据:', data)
    
    return data.step_action || []
  } catch (error) {
    console.error('获取基站状态失败:', error)
    return []
  }
}

// 获取用户数据
const fetchUserData = async (moment: number) => {
  try {
    console.log(`正在获取时刻 ${moment} 的用户数据...`)
    const response = await fetch(`${API_BASE_URL}/getmapdata_user?moment=${moment}`)
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    
    const data = await response.json()
    console.log('用户数据:', data)
    
    return data.step_state || []
  } catch (error) {
    console.error('获取用户数据失败:', error)
    return []
  }
}

// 加载真实数据
const loadRealData = async () => {
  isLoading.value = true
  loadingError.value = null
  
  try {
    console.log('开始加载真实数据...')
    
    // 获取基站位置
    const baseStationLocations = await fetchBaseStationLocations()
    
    // 获取当前时刻的基站状态
    const baseStationStatus = await fetchBaseStationData(CURRENT_MOMENT.value)
    
    // 获取用户数据
    const userData = await fetchUserData(CURRENT_MOMENT.value)
    
    // 合并基站位置和状态信息
    baseStations.value = baseStationLocations.map(location => {
      const status = baseStationStatus.find((bs: any) => bs.bs_id === location.id)
      return {
        ...location,
        type: '5G', // 假设都是5G基站
        coverage: `${Math.round(location.transmit_power * 20)}m`, // 根据发射功率估算覆盖范围
        status: status ? '正常' : '离线',
        power: status?.bs_power || 0,
        azimuth: status?.bs_azi || 0,
        tilt: status?.bs_tilt || 0,
        changeConfig: status?.bs_changeconfig || 0,
        prbAllocations: status?.PRB_allocation || []
      }
    })
    
    // 直接使用原始x/y作为lng/lat
    users.value = userData.map((user: any) => {
      // 检查坐标数据是否有效
      if (!user.x || !user.y || isNaN(user.x) || isNaN(user.y)) {
        console.warn(`用户 ${user.id} 坐标数据无效:`, user);
        return null; // 跳过无效数据
      }
      // 根据信号功率确定信号强度
      let signal = '弱'
      if (user.received_power > -80) signal = '强'
      else if (user.received_power > -90) signal = '中'
      // 根据device_type确定设备类型
      const deviceTypes = ['iPhone 15', 'Samsung S24', 'Huawei P60', 'Xiaomi 14', 'OPPO Find X7', 'Vivo X100']
      const device = deviceTypes[user.device_type % deviceTypes.length]
      // 找到连接的基站名称
      const connectedBase = baseStations.value.find(bs => bs.id === user.BaseStationId)
      return {
        id: user.id,
        name: `用户${user.id}`,
        lat: user.y,
        lng: user.x,
        device,
        signal,
        connected_base: connectedBase ? connectedBase.name : `基站${user.BaseStationId}`,
        base_station_id: user.BaseStationId,
        demand: user.demand,
        remain_time: user.remain_time,
        satisfied_flow: user.satisfied_flow,
        demand_next_average: user.demand_next_average,
        received_power: user.received_power,
        interference_power: user.interference_power,
        device_type: user.device_type,
        original_x: user.x,
        original_y: user.y
      };
    }).filter((user: any) => user !== null); // 过滤掉无效用户
    
    console.log(`成功加载了 ${baseStations.value.length} 个基站和 ${users.value.length} 个用户`)
    
    // 检查用户数据的分布
    if (users.value.length > 0) {
      const latitudes = users.value.map(u => u.lat);
      const longitudes = users.value.map(u => u.lng);
      const minLat = Math.min(...latitudes);
      const maxLat = Math.max(...latitudes);
      const minLng = Math.min(...longitudes);
      const maxLng = Math.max(...longitudes);
      
      console.log(`用户位置范围: 纬度 ${minLat.toFixed(6)} - ${maxLat.toFixed(6)}, 经度 ${minLng.toFixed(6)} - ${maxLng.toFixed(6)}`);
      
      // 检查是否所有用户都在地图可视范围内
      const mapBounds = {
        minLat: DEFAULT_VIEW.value.lat - 0.05,
        maxLat: DEFAULT_VIEW.value.lat + 0.05,
        minLng: DEFAULT_VIEW.value.lng - 0.05,
        maxLng: DEFAULT_VIEW.value.lng + 0.05
      };
      
      const usersInBounds = users.value.filter(u => 
        u.lat >= mapBounds.minLat && u.lat <= mapBounds.maxLat &&
        u.lng >= mapBounds.minLng && u.lng <= mapBounds.maxLng
      );
      
      console.log(`地图可视范围内的用户数量: ${usersInBounds.length}/${users.value.length}`);
      
      if (usersInBounds.length === 0) {
        console.warn('没有用户在当前地图可视范围内，可能需要调整地图中心或缩放级别');
      }
    }
    
    console.log('用户数据示例:', users.value.slice(0, 3)) // 显示前3个用户的数据
    console.log('基站数据示例:', baseStations.value.slice(0, 2)) // 显示前2个基站的数据
    
  } catch (error) {
    console.error('加载数据失败:', error)
    loadingError.value = `加载数据失败: ${error instanceof Error ? error.message : '未知错误'}`
  } finally {
    isLoading.value = false
  }
}

// 创建聚合三角形图标（基站）
const createClusterTriangleIcon = (color: string = '#ff4444', count: number = 1) => {
  const size = Math.min(Math.max(16 + count * 2, 16), 32)
  return L.divIcon({
    html: `
      <div style="position: relative;">
        <div style="
          width: 0;
          height: 0;
          border-left: ${size/2}px solid transparent;
          border-right: ${size/2}px solid transparent;
          border-bottom: ${size}px solid ${color};
          transform: translateX(-${size/2}px) translateY(-${size/2}px);
        "></div>
        ${count > 1 ? `
          <div style="
            position: absolute;
            top: -${size/2 + 16}px;
            left: -${size/2}px;
            width: ${size}px;
            text-align: center;
            background: rgba(0,0,0,0.7);
            color: white;
            border-radius: 10px;
            font-size: 10px;
            padding: 2px 4px;
            font-weight: bold;
          ">${count}</div>
        ` : ''}
      </div>
    `,
    className: 'triangle-cluster-marker',
    iconSize: [size, size],
    iconAnchor: [size/2, size/2]
  })
}

// 创建聚合圆形图标（用户）
const createClusterCircleIcon = (color: string = '#4444ff', count: number = 1) => {
  const size = Math.min(Math.max(12 + count, 12), 28)
  return L.divIcon({
    html: `
      <div style="position: relative;">
        <div style="
          width: ${size}px;
          height: ${size}px;
          border-radius: 50%;
          background-color: ${color};
          border: 2px solid white;
          box-shadow: 0 2px 4px rgba(0,0,0,0.3);
          transform: translateX(-${(size+4)/2}px) translateY(-${(size+4)/2}px);
        "></div>
        ${count > 1 ? `
          <div style="
            position: absolute;
            top: -${(size+4)/2 + 16}px;
            left: -${(size+4)/2}px;
            width: ${size+4}px;
            text-align: center;
            background: rgba(0,0,0,0.7);
            color: white;
            border-radius: 8px;
            font-size: 9px;
            padding: 1px 3px;
            font-weight: bold;
          ">${count}</div>
        ` : ''}
      </div>
    `,
    className: 'circle-cluster-marker',
    iconSize: [size+4, size+4],
    iconAnchor: [(size+4)/2, (size+4)/2]
  })
}

// 计算两点之间的距离（千米）
const calculateDistance = (lat1: number, lng1: number, lat2: number, lng2: number): number => {
  const R = 6371 // 地球半径（千米）
  const dLat = (lat2 - lat1) * Math.PI / 180
  const dLng = (lng2 - lng1) * Math.PI / 180
  const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    Math.sin(dLng/2) * Math.sin(dLng/2)
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
  return R * c
}

// 根据缩放级别进行聚合
const clusterItems = (items: any[], zoomLevel: number, threshold: number = 0.5) => {
  if (zoomLevel >= 15) return items.map(item => ({ ...item, count: 1, items: [item] }))
  
  const clustered: any[] = []
  const used: boolean[] = new Array(items.length).fill(false)
  const clusterRadius = threshold / Math.pow(2, zoomLevel - 10) // 根据缩放级别调整聚合半径
  
  items.forEach((item, i) => {
    if (used[i]) return
    
    const cluster = {
      ...item,
      count: 1,
      items: [item],
      totalSignalStrength: item.signal === '强' ? 3 : item.signal === '中' ? 2 : 1,
      statusCounts: { 正常: 0, 维护中: 0 },
      typeCounts: { '5G': 0, '4G': 0 }
    }
    
    // 初始化状态计数
    if (item.status) {
      cluster.statusCounts[item.status] = 1
    }
    if (item.type) {
      cluster.typeCounts[item.type] = 1
    }
    
    used[i] = true
    
    // 查找邻近的点进行聚合
    items.forEach((otherItem, j) => {
      if (used[j] || i === j) return
      
      const distance = calculateDistance(item.lat, item.lng, otherItem.lat, otherItem.lng)
      if (distance <= clusterRadius) {
        cluster.count++
        cluster.items.push(otherItem)
        cluster.lat = (cluster.lat * (cluster.count - 1) + otherItem.lat) / cluster.count
        cluster.lng = (cluster.lng * (cluster.count - 1) + otherItem.lng) / cluster.count
        
        // 累计信号强度
        if (otherItem.signal) {
          cluster.totalSignalStrength += otherItem.signal === '强' ? 3 : otherItem.signal === '中' ? 2 : 1
        }
        
        // 累计状态计数
        if (otherItem.status) {
          cluster.statusCounts[otherItem.status] = (cluster.statusCounts[otherItem.status] || 0) + 1
        }
        
        // 累计类型计数
        if (otherItem.type) {
          cluster.typeCounts[otherItem.type] = (cluster.typeCounts[otherItem.type] || 0) + 1
        }
        
        used[j] = true
      }
    })
    
    // 计算平均信号强度
    if (cluster.totalSignalStrength) {
      const avgSignal = cluster.totalSignalStrength / cluster.count
      cluster.signal = avgSignal >= 2.5 ? '强' : avgSignal >= 1.5 ? '中' : '弱'
    }
    
    // 确定主要状态
    if (cluster.statusCounts) {
      cluster.status = cluster.statusCounts.正常 >= cluster.statusCounts.维护中 ? '正常' : '维护中'
    }
    
    // 确定主要类型
    if (cluster.typeCounts) {
      cluster.type = cluster.typeCounts['5G'] >= cluster.typeCounts['4G'] ? '5G' : '4G'
    }
    
    clustered.push(cluster)
  })
  
  return clustered
}

// 创建基站标记
const createBaseStationMarkers = (zoomLevel: number) => {
  if (baseStationMarkers) {
    map!.removeLayer(baseStationMarkers)
  }
  
  baseStationMarkers = L.layerGroup()
  const clusteredStations = clusterItems(baseStations.value, zoomLevel, 0.5)
  
  clusteredStations.forEach(station => {
    const color = station.status === '正常' ? '#00aa00' : '#ffaa00'
    const marker = L.marker([station.lat, station.lng], {
      icon: createClusterTriangleIcon(color, station.count)
    })
    
    // 创建基站popup内容
    let popupContent = `<div class="marker-popup">`
    if (station.count === 1) {
      popupContent += `
        <h3>${station.name}</h3>
        <p><strong>基站ID:</strong> ${station.id}</p>
        <p><strong>类型:</strong> ${station.type}</p>
        <p><strong>覆盖范围:</strong> ${station.coverage}</p>
        <p><strong>状态:</strong> <span style="color: ${color}">${station.status}</span></p>
        <p><strong>发射功率:</strong> ${station.transmit_power || station.power || 'N/A'}dBm</p>
        ${station.azimuth !== undefined ? `<p><strong>方位角:</strong> ${station.azimuth}°</p>` : ''}
        ${station.tilt !== undefined ? `<p><strong>下倾角:</strong> ${station.tilt}°</p>` : ''}
        ${station.prbAllocations && station.prbAllocations.length > 0 ? `<p><strong>连接用户数:</strong> ${station.prbAllocations.length}</p>` : ''}
      `
    } else {
      popupContent += `
        <h3>基站集群 (${station.count}个)</h3>
        <p><strong>主要类型:</strong> ${station.type}</p>
        <p><strong>主要状态:</strong> <span style="color: ${color}">${station.status}</span></p>
        <p><strong>包含基站:</strong></p>
        <ul style="margin: 4px 0; padding-left: 16px; max-height: 100px; overflow-y: auto;">
      `
      station.items.forEach((item: any) => {
        popupContent += `<li style="font-size: 12px;">${item.name} (${item.type})</li>`
      })
      popupContent += `</ul>`
    }
    popupContent += `</div>`
    
    marker.bindPopup(popupContent)
    
    // 创建基站tooltip
    const tooltipContent = station.count === 1 
      ? `<div class="marker-tooltip"><strong>${station.name}</strong><br/>${station.type} | ${station.status}</div>`
      : `<div class="marker-tooltip"><strong>基站集群</strong><br/>${station.count}个基站 | ${station.type}</div>`
    
    marker.bindTooltip(tooltipContent, {
      permanent: false,
      direction: 'top',
      offset: [0, -10]
    })
    
    if (baseStationMarkers) {
      baseStationMarkers.addLayer(marker)
    }
  })
  
  if (baseStationMarkers && map) {
    baseStationMarkers.addTo(map)
  }
}

// 创建用户标记
const createUserMarkers = (zoomLevel: number) => {
  console.log(`开始创建用户标记，缩放级别: ${zoomLevel}, 用户数量: ${users.value.length}`)
  
  if (userMarkers) {
    map!.removeLayer(userMarkers)
  }
  
  userMarkers = L.layerGroup()
  const clusteredUsers = clusterItems(users.value, zoomLevel, 0.3)
  
  console.log(`聚合后的用户数量: ${clusteredUsers.length}`)
  
  clusteredUsers.forEach(user => {
    console.log(`创建用户标记: ${user.name} at (${user.lat}, ${user.lng})`)
    
    let color = '#4444ff'
    // 根据信号强度设置颜色
    switch (user.signal) {
      case '强':
        color = '#00aa00'
        break
      case '中':
        color = '#ffaa00'
        break
      case '弱':
        color = '#ff4444'
        break
    }
    
    const marker = L.marker([user.lat, user.lng], {
      icon: createClusterCircleIcon(color, user.count)
    })
    
    // 创建用户popup内容
    let popupContent = `<div class="marker-popup">`
    if (user.count === 1) {
      popupContent += `
        <h3>${user.name}</h3>
        <p><strong>用户ID:</strong> ${user.id}</p>
        <p><strong>设备:</strong> ${user.device}</p>
        <p><strong>信号强度:</strong> <span style="color: ${color}">${user.signal}</span></p>
        <p><strong>接收功率:</strong> ${user.received_power?.toFixed(2) || 'N/A'}dBm</p>
        <p><strong>连接基站:</strong> ${user.connected_base}</p>
        <p><strong>需求流量:</strong> ${user.demand?.toFixed(3) || 'N/A'}Mbps</p>
        <p><strong>满足流量:</strong> ${user.satisfied_flow?.toFixed(3) || 'N/A'}Mbps</p>
        ${user.remain_time !== undefined ? `<p><strong>剩余时间:</strong> ${user.remain_time}s</p>` : ''}
      `
    } else {
      popupContent += `
        <h3>用户集群 (${user.count}个)</h3>
        <p><strong>平均信号:</strong> <span style="color: ${color}">${user.signal}</span></p>
        <p><strong>设备分布:</strong></p>
        <div style="font-size: 12px; max-height: 80px; overflow-y: auto;">
      `
      const deviceCounts: {[key: string]: number} = {}
      user.items.forEach((item: any) => {
        deviceCounts[item.device] = (deviceCounts[item.device] || 0) + 1
      })
      Object.entries(deviceCounts).forEach(([device, count]) => {
        popupContent += `<p style="margin: 2px 0;">${device}: ${count}个</p>`
      })
      popupContent += `</div>`
    }
    popupContent += `</div>`
    
    marker.bindPopup(popupContent)
    
    // 创建用户tooltip
    const tooltipContent = user.count === 1
      ? `<div class="marker-tooltip"><strong>${user.name}</strong><br/>${user.device} | 信号: ${user.signal}</div>`
      : `<div class="marker-tooltip"><strong>用户集群</strong><br/>${user.count}个用户 | 信号: ${user.signal}</div>`
    
    marker.bindTooltip(tooltipContent, {
      permanent: false,
      direction: 'top',
      offset: [0, -10]
    })
    
    if (userMarkers) {
      userMarkers.addLayer(marker)
    }
  })
  
  if (userMarkers && map) {
    userMarkers.addTo(map)
  }
}

// 更新当前中心点
const updateCurrentCenter = () => {
  if (!map) return
  const center = map.getCenter()
  currentCenter.value = { lat: center.lat, lng: center.lng }
}

// 重置到默认视角
const resetToDefaultView = () => {
  if (!map) return
  
  map.setView([DEFAULT_VIEW.value.lat, DEFAULT_VIEW.value.lng], DEFAULT_VIEW.value.zoom, {
    animate: true,
    duration: 1.0 // 动画持续时间（秒）
  })
  
  // 立即更新状态以反映变化
  setTimeout(() => {
    updateCurrentCenter()
    updateMarkers()
  }, 100)
}

// 更新标记（根据缩放级别）
const updateMarkers = () => {
  if (!map) return
  const zoomLevel = map.getZoom()
  currentZoomLevel.value = zoomLevel
  updateCurrentCenter()
  createBaseStationMarkers(zoomLevel)
  createUserMarkers(zoomLevel)
}

// 初始化地图
const initMap = async () => {
  // 测试UTM转换函数
  testUtmConversion()
  
  // 先加载真实数据
  await loadRealData()
  
  // 根据基站数据计算默认视角
  if (baseStations.value.length > 0) {
    const bounds = calculateBaseStationBounds(baseStations.value);
    DEFAULT_VIEW.value = {
      lat: bounds.center.lat,
      lng: bounds.center.lng,
      zoom: bounds.zoom
    };
    
    // 更新当前中心点
    currentCenter.value = { lat: bounds.center.lat, lng: bounds.center.lng };
    currentZoomLevel.value = bounds.zoom;
    
    console.log(`使用计算出的默认视角: (${bounds.center.lat.toFixed(6)}, ${bounds.center.lng.toFixed(6)}), 缩放: ${bounds.zoom}`);
  }
  
  // 创建地图实例，使用计算出的中心点
  map = L.map('map').setView([DEFAULT_VIEW.value.lat, DEFAULT_VIEW.value.lng], DEFAULT_VIEW.value.zoom)

  // 添加OpenStreetMap图层
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  }).addTo(map)

  // 监听缩放事件
  map.on('zoomend', updateMarkers)
  
  // 监听地图移动事件（拖拽、平移等）
  map.on('moveend', updateCurrentCenter)
  
  // 初始化当前中心点
  updateCurrentCenter()
  
  // 初始加载标记
  updateMarkers()
  
  // 启动自动刷新
  startAutoRefresh()
}

onMounted(() => {
  initMap()
})

onUnmounted(() => {
  // 停止自动刷新
  stopAutoRefresh()
  
  if (map) {
    map.remove()
    map = null
  }
  baseStationMarkers = null
  userMarkers = null
})
</script>

<style scoped>
.base-geo-container {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.map-header {
  padding: 16px;
  background-color: #fff;
  border-bottom: 1px solid #e8e8e8;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.map-header h2 {
  margin: 0;
  color: #333;
  font-size: 20px;
}

.header-controls {
  display: flex;
  gap: 30px;
  align-items: center;
}

.time-selector {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #666;
}

.time-selector label {
  font-weight: 500;
}

.time-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: #666;
  min-width: 120px;
  margin: 4px 0;
}

.current-time {
  color: #1890ff;
  font-weight: bold;
}

.auto-refresh-indicator {
  font-size: 11px;
  color: #999;
  transition: color 0.3s ease;
}

.auto-refresh-indicator.active {
  color: #52c41a;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

.moment-select {
  padding: 4px 8px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background: white;
  font-size: 12px;
  min-width: 80px;
  cursor: pointer;
}

.moment-select:focus {
  outline: none;
  border-color: #1890ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

.zoom-info {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 12px;
  color: #666;
  background: #f5f5f5;
  padding: 8px 12px;
  border-radius: 6px;
  gap: 4px;
}

.zoom-hint {
  font-weight: bold;
  color: #1890ff;
}

.reset-view-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  font-size: 11px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background: white;
  color: #595959;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-top: 2px;
}

.reset-view-btn:hover:not(:disabled) {
  border-color: #1890ff;
  color: #1890ff;
  background: #f0f9ff;
}

.reset-view-btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
  background: #f5f5f5;
}

.reset-view-btn svg {
  flex-shrink: 0;
}

.legend {
  display: flex;
  gap: 20px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #666;
}

.legend-icon {
  width: 16px;
  height: 16px;
  position: relative;
}

.legend-icon.triangle {
  width: 0;
  height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-bottom: 16px solid #00aa00;
}

.legend-icon.circle {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: #4444ff;
  border: 2px solid white;
  box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}

.legend-item.loading {
  color: #1890ff;
}

.loading-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid #f3f3f3;
  border-top: 2px solid #1890ff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.legend-item.error {
  color: #ff4d4f;
  font-size: 12px;
  max-width: 200px;
}

.error-icon {
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}

.map-container {
  flex: 1;
  width: 100%;
  min-height: 500px;
}

/* 自定义leaflet样式 */
:deep(.marker-popup) {
  font-family: Arial, sans-serif;
}

:deep(.marker-popup h3) {
  margin: 0 0 8px 0;
  color: #333;
  font-size: 16px;
}

:deep(.marker-popup p) {
  margin: 4px 0;
  font-size: 14px;
  color: #666;
}

:deep(.marker-tooltip) {
  font-size: 12px;
  text-align: center;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  border: none;
  box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}

:deep(.leaflet-tooltip) {
  background: transparent;
  border: none;
  box-shadow: none;
}

:deep(.leaflet-tooltip-top:before) {
  border-top-color: rgba(0, 0, 0, 0.8);
}

/* 聚合标记样式 */
:deep(.triangle-cluster-marker),
:deep(.circle-cluster-marker) {
  transition: transform 0.2s ease;
}

:deep(.triangle-cluster-marker:hover),
:deep(.circle-cluster-marker:hover) {
  transform: scale(1.1);
  z-index: 1000;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .map-header {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
  }

  .map-header h2 {
    font-size: 18px;
  }

  .header-controls {
    width: 100%;
    justify-content: space-between;
    gap: 15px;
    flex-wrap: wrap;
  }

  .time-selector {
    font-size: 13px;
    gap: 6px;
  }

  .moment-select {
    font-size: 11px;
    padding: 3px 6px;
    min-width: 70px;
  }

  .zoom-info {
    font-size: 11px;
    padding: 6px 10px;
    gap: 3px;
  }

  .reset-view-btn {
    font-size: 10px;
    padding: 3px 6px;
    gap: 3px;
  }

  .reset-view-btn svg {
    width: 14px;
    height: 14px;
  }

  .legend {
    gap: 15px;
  }

  .legend-item {
    font-size: 13px;
  }
}
</style>